package com.google.code.syncgear.plugin.dispatch;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.Validate;
import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.tags.InputTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.SimpleNodeIterator;

import weibo4j.Weibo;
import weibo4j.WeiboException;
import weibo4j.http.AccessToken;
import weibo4j.http.HttpClient;
import weibo4j.http.PostParameter;
import weibo4j.http.RequestToken;
import weibo4j.http.Response;

import com.google.code.syncgear.plugin.AbstractDispatch;
import com.google.code.syncgear.plugin.bean.FetchResult;

public final class SinaWeiboDispatch extends AbstractDispatch {

	private static final long serialVersionUID = -8028915346452500074L;
	
	private static final Logger log = Logger.getLogger(SinaWeiboDispatch.class.getName());
	
	private Weibo weibo;
	private RequestToken requestToken;
	private String token;
	private String tokenSecret;
	
	@Override
	protected boolean init(List<String> target) {
		try {
			String consumerKey = target.get(0);
			String consumerSecret = target.get(1);
			System.setProperty("weibo4j.oauth.consumerKey", consumerKey);
			System.setProperty("weibo4j.oauth.consumerSecret", consumerSecret);
			weibo = new Weibo();
		} catch (Exception e) {
			log.warning(e.getMessage());
			return false;
		}
		return true;		
	}
	
	@Override
	protected boolean auth(List<String> target) {
		boolean isAuthed = true;
		Object freezeObject = this.unfreeze(target);
		if(freezeObject != null) {
			SinaWeiboFreezeObject sinaWeiboFreezeObject = (SinaWeiboFreezeObject) freezeObject;
			weibo = sinaWeiboFreezeObject.getWeibo();
			token = sinaWeiboFreezeObject.getToken();
			tokenSecret = sinaWeiboFreezeObject.getTokenSecret();
		} else {
			try {
				String consumerKey = target.get(0);
				String userId = target.get(2);
				String password = target.get(3);		
		    	requestToken = weibo.getOAuthRequestToken();
		    	Parser parser = new Parser();
		    	String url = requestToken.getAuthorizationURL();
		    	parser.setURL(url);
				parser.setEncoding(parser.getEncoding());		
				NodeList nodeList = parser.parse(new NodeClassFilter(InputTag.class));		
				SimpleNodeIterator simpleNodeIterator = nodeList.elements();
				List<PostParameter> postParameterList = new ArrayList<PostParameter>();
				while (simpleNodeIterator.hasMoreNodes()) {
					Node node = simpleNodeIterator.nextNode();
					InputTag inputnode = (InputTag) node;
					String name = inputnode.getAttribute("name");
					String value = inputnode.getAttribute("value");
					if (name.equals("userId"))
						value = userId;
					else if (name.equals("passwd"))
						value = password;
					try {
						Validate.notNull(value);
						PostParameter pp = new PostParameter(name, value);
						postParameterList.add(pp);
					} catch (IllegalArgumentException e) {
					}			
				}		
				PostParameter[] postParameters = postParameterList.toArray(new PostParameter[0]);
				String response = requestToken.getHttpClient().post(url, postParameters).asString();
				Pattern pattern = Pattern.compile("<span class=\"fb\">.*</span>");
				Matcher matcher = pattern.matcher(response);
				String pin = "";
				while (matcher.find())
				{  
				   pin = response.substring(matcher.start(), matcher.end()).replace("<span class=\"fb\">", "").replace("</span>", "");
				   break;
				}
				try {
					Validate.notEmpty(pin);
					AccessToken accessToken = requestToken.getAccessToken(pin);
					token = accessToken.getToken();
					tokenSecret = accessToken.getTokenSecret();
					
				} catch (IllegalArgumentException e) {					
					isAuthed = false;
					log.warning(e.getMessage());
				}
				weibo.setToken(token, tokenSecret);
				weibo.setSource(consumerKey);

				SinaWeiboFreezeObject sinaWeiboFreezeObject = new SinaWeiboFreezeObject();
				sinaWeiboFreezeObject.setToken(token);
				sinaWeiboFreezeObject.setTokenSecret(tokenSecret);
				sinaWeiboFreezeObject.setWeibo(weibo);
				this.freeze(target, sinaWeiboFreezeObject);
			} catch (Exception ex) {
				isAuthed = false;
				log.warning(ex.getMessage());
			}
		}		
		return isAuthed;
	}

	@Override
	protected boolean process(List<String> target, FetchResult fetchResult) {
		boolean isSuccess = true;		
		try {
			String message = fetchResult.getTitle();
			String consumerKey = target.get(0);
			String consumerSecret = target.get(1);
			if(message == null)
				message = "";
			
			if(fetchResult.getLink() != null)
				message = message + "  " + fetchResult.getLink();
			
			if(fetchResult.getImage() != null) {
				if(fetchResult.getImage().trim().length() > 0) {
					try {
			        	String msgId = upload(consumerKey, consumerSecret, token, tokenSecret, message, fetchResult.getImage());
			        	if(msgId.length() == 0) {
			        		weibo.updateStatus(message);
			        	}
			     	} catch (Exception exception) {
			     		log.warning(exception.getMessage());
						weibo.updateStatus(message);
					}
				}
			} else {
				weibo.updateStatus(message);
			}
		} catch (Exception ex) {
			isSuccess = false;
			log.warning(ex.getMessage());
		}
		return isSuccess;
	}
	
	private String upload(String consumerKey, String consumerSecret, String tokenKey, String tokenSecret, String message, String url) {
		String result = "";
		List<PostParameter> postParameterList = new ArrayList<PostParameter>();
        postParameterList.add(new PostParameter("WB_AKEY", consumerKey));
        postParameterList.add(new PostParameter("WB_SKEY", consumerSecret));
        postParameterList.add(new PostParameter("WB_TOKEN", tokenKey));
        postParameterList.add(new PostParameter("WB_SECRET", tokenSecret));
        postParameterList.add(new PostParameter("text", message));
        postParameterList.add(new PostParameter("pic", url));
        PostParameter[] postParameters = postParameterList.toArray(new PostParameter[0]);        
        HttpClient client = new HttpClient();        
        try {
        	Response response = client.post("http://syncgear.sinaapp.com/service/upload.php", postParameters);
			log.info(response.getResponseAsString());
        	result = response.asString().trim();
		} catch (WeiboException e) {
			log.warning(e.getMessage());
		}
		return result;
	}

}
